﻿#region

using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Logging;
using Vin.Tool.AspNetCore.Options;
using Vin.Tool.AspNetCore.Singleton;
using Vin.Tool.Core.NetCategory;
using Vin.Tool.Domain.ExceptionModel;

#endregion

namespace Vin.Tool.AspNetCore.Filter;

/// <summary>
/// IP授权，指定ip可以访问（需要在app settings.json指定 AuthIP 字符串数组类型）
/// </summary>
public class IpAuthActionFilter : Attribute, IAsyncActionFilter
{
    private ILogger<IpAuthActionFilter>? _logger;

    private VinIpAuthOption? _option;

    public virtual async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
    {
        _logger = VinApp.GetLogger<IpAuthActionFilter>();
        _option = VinApp.GetConfig<VinIpAuthOption>();

        var ip = context.HttpContext.GetClientUserIp();

        // 走白名单
        if (_option.WhiteList.Count > 0 && !_option.WhiteList.Contains(ip))
        {
            _logger.LogWarning($"IP: {ip} 不在白名单中.");
            throw new ErrorException(StatusCodes.Status401Unauthorized, "IP不在白名单中.");
        }

        // 走黑名单
        if (_option.BlackList.Count > 0 && _option.BlackList.Contains(ip))
        {
            _logger.LogWarning($"IP: {ip} 在黑名单中.");
            throw new ErrorException(StatusCodes.Status401Unauthorized, "IP在黑名单中.");
        }

        await next();
    }
}